package org.syx.edl.nio;


import cn.hutool.core.util.StrUtil;
import org.syx.edl.ItemReader;
import org.syx.edl.LineMapper;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;

/**
 * @author:whh
 * @date: 2025-09-04 22:00
 * <p></p>
 */
public class ByteLineReader<T> implements ItemReader<T> {
    private ByteBuffer buf;
    private int start;
    private int len;
    private byte[] data;

    private int lineCount;

    private LineMapper<T> lineMapper;


    public ByteLineReader(ByteBuffer buf, LineMapper<T> lineMapper) {
        this.buf=buf;
        this.len=buf.remaining();
        this.lineMapper=lineMapper;
    }

    private String readLine(){
        String line;
        for (int i = start; i < len; i++) {
            if(data[i]=='\r' && i+1<len && data[i+1]=='\n'){
                line=new String(data,start,i-start, StandardCharsets.UTF_8);
                start=i+2;
                return line;
            } else if (data[i]=='\n') {
                line=new String(data,start,i-start, StandardCharsets.UTF_8);
                start=i+1;
                return line;
            }
        }
        line=new String(data,start,len-start,StandardCharsets.UTF_8);
        start=len;
        return line;
    }

    @Override
    public void open() throws Exception {
        this.data=new byte[len];
        buf.get(data);
    }


    @Override
    public boolean hasNext() {
        return start<len;
    }

    @Override
    public T next() throws Exception {
        String line = readLine();
        if(!StrUtil.isNotEmpty(line)){
            return null;
        }
        return lineMapper.mapLine(line,++lineCount);

    }

    @Override
    public void flip() {
        start=0;
        lineCount=0;
    }

    @Override
    public void close() throws Exception {
        data=null;
        buf=null;
    }
}
